home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Information / Digests / CSMP Digest / volume 3 / csmp-digest-v3-067 < prev    next >
Encoding:
Text File  |  1994-12-08  |  129.1 KB  |  1,939 lines  |  [TEXT/R*ch]

  1. C.S.M.P. Digest             Mon, 14 Nov 94       Volume 3 : Issue 67
  2.  
  3. Today's Topics:
  4.  
  5.         (Q) AppleScript & XCMD's
  6.         Can anyone help me with the Time Manager?
  7.         Dynamic Dialogs?
  8.         How to install your own templates using Macsbug 6.5d6???
  9.         IM: Networking book question
  10.         INIT Writing FAQ [1-3]
  11.         INIT Writing FAQ [2-3]
  12.         INIT Writing FAQ [3-3]
  13.         Linking 68k object files to PPC program
  14.         Network Programming
  15.         Stuck in SyncWait again
  16.         having trouble with AEInteractWithUser & drag manager
  17.  
  18.  
  19.  
  20. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  21. (pottier@clipper.ens.fr).
  22.  
  23. The digest is a collection of article threads from the internet newsgroup
  24. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  25. regularly and want an archive of the discussions.  If you don't know what a
  26. newsgroup is, you probably don't have access to it.  Ask your systems
  27. administrator(s) for details.  If you don't have access to news, you may
  28. still be able to post messages to the group by using a mail server like
  29. anon.penet.fi (mail help@anon.penet.fi for more information).
  30.  
  31. Each issue of the digest contains one or more sets of articles (called
  32. threads), with each set corresponding to a 'discussion' of a particular
  33. subject.  The articles are not edited; all articles included in this digest
  34. are in their original posted form (as received by our news server at
  35. nef.ens.fr).  Article threads are not added to the digest until the last
  36. article added to the thread is at least two weeks old (this is to ensure that
  37. the thread is dead before adding it to the digest).  Article threads that
  38. consist of only one message are generally not included in the digest.
  39.  
  40. The digest is officially distributed by two means, by email and ftp.
  41.  
  42. If you want to receive the digest by mail, send email to listserv@ens.fr
  43. with no subject and one of the following commands as body:
  44.     help                        Sends you a summary of commands
  45.     subscribe csmp-digest Your Name    Adds you to the mailing list
  46.     signoff csmp-digest            Removes you from the list
  47. Once you have subscribed, you will automatically receive each new
  48. issue as it is created.
  49.  
  50. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  51. Questions related to the ftp site should be directed to
  52. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  53. digest are available there.
  54.  
  55. Also, the digests are available to WAIS users.  To search back issues
  56. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  57. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  58.  
  59.  
  60. -------------------------------------------------------
  61.  
  62. >From Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill)
  63. Subject: (Q) AppleScript & XCMD's
  64. Date: 31 Oct 1994 19:07:41 GMT
  65. Organization: MacInTouch BBS
  66.  
  67. Can anyone tell me whether XCMD's (typically for HyperCard) can be included
  68. in
  69. and accessed by a compiled AppleScript application, without running a
  70. separate HyperCard process?
  71. Thanks,
  72. Tom
  73. please email to tombh@intouch.mpx.com.au
  74. and post too for others.
  75.                             MacInTouch BBS
  76. info@intouch.mpx.com.au     Ph. 61 2 541 1287    BBS. 61 2 541 0799
  77. *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
  78.  
  79. +++++++++++++++++++++++++++
  80.  
  81. >From lai@apple.com (Ed Lai)
  82. Date: Mon, 31 Oct 1994 17:20:39 GMT
  83. Organization: Apple
  84.  
  85. In article <29224926.900353@intouch.intouch.mpx.com.au>,
  86. Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill) wrote:
  87.  
  88. > Can anyone tell me whether XCMD's (typically for HyperCard) can be included
  89. in
  90. > and accessed by a compiled AppleScript application, without running a
  91. > separate HyperCard process?
  92. > Thanks,
  93. > Tom
  94. > please email to tombh@intouch.mpx.com.au
  95. > and post too for others.
  96. >                             MacInTouch BBS
  97. > info@intouch.mpx.com.au     Ph. 61 2 541 1287    BBS. 61 2 541 0799
  98. > *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
  99.  
  100. It depends on the XCMD, a lot of them can be used, but if they are
  101. very dependent on HyperCard specifc callback or globals, then they
  102. cannot.
  103.  
  104. Try to download the XCMD OSAX.
  105.  
  106. Generally the place to look for AppleScript related stuff is in
  107. gaea.kgs.ukans.edu.
  108.  
  109. If it is just for the XCMD OSAX, you may try ftp.apple.com in
  110. /pub/lai/osax.
  111.  
  112. It is an adaptor for AppleScript to use XCMDs. It also comes installed
  113. with a number of XCMDs by Rinaldi as examples.
  114.  
  115. In theory you can try it with any other XCMD/XFCNs you got. However to
  116. do that requires writing certain resources and that is not a easy
  117. job if you are doing it the first time.
  118.  
  119. -- 
  120. /* Disclaimer: All statments and opinions expressed are my own */
  121. /* Edmund K. Lai                                               */
  122. /* Apple Computer, MS303-3A                                    */
  123. /* 20525 Mariani Ave,                                          */
  124. /* Cupertino, CA 95014                                         */
  125. /* (408)974-6272                                               */
  126. zW@h9cOi
  127.  
  128. ---------------------------
  129.  
  130. >From anthonym@puree.ugcs.caltech.edu (Anthony Molinaro)
  131. Subject: Can anyone help me with the Time Manager?
  132. Date: 21 Oct 1994 08:09:59 GMT
  133. Organization: California Institute of Technology, Pasadena
  134.  
  135.  
  136. I worked on this piece of code for a friend using Symatec 
  137. THINK C which turns on the power to a digital I/O board, 
  138. delays for a certain number of ticks, and then turns the 
  139. power off. This was my first time programming on a Macintosh 
  140. and so I had to search a little bit to find out about Delay.  
  141. Now, he tells me he needs a delay time smaller than one tick.  
  142. I know that the time manager can do this but I have been 
  143. unable to get it to work.  I guess my confusion arises in the
  144. type declarations and getting all of the types to match for 
  145. functions InsXTime(), PrimeTime(), and such.  The Inside 
  146. Macintosh doesn't have any examples in C and I have not been 
  147. able to accurately port the Pascal functions with the proper
  148. type settings.  My midterms are quickly approaching but I 
  149. promised I would help him out, so any help that anyone could
  150. give would be .
  151.  
  152.  
  153.  
  154. /* Here is the original code */
  155.  
  156. void Play(int note, unsigned long time)
  157. {  long finalTicks;
  158.    short error;
  159.  
  160.    /* turn on power for port,line: portout, lineout */
  161.    error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 1);
  162.    chkerr("DIG_Out_Line",error);
  163.  
  164.    /* if power is on delay */
  165.    if(error == 0)
  166.      Delay(time,&finalTicks);
  167.  
  168.    /* turn off power */
  169.    error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  170.    chkerr("DIG_Out_Line",error);
  171. }
  172.  
  173. /* Here is what I tryed */
  174. /* global variables     */
  175.  
  176. int note;
  177. TMTask tblah;
  178.  
  179. pascal void MyTimeTask(void)
  180. { DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  181. }
  182.  
  183. void MyDelay(unsigned long time)
  184. { tblah.tmAddr = &MyTimeTask();
  185.   tblah.tmWakeUp = 0;
  186.   tblah.tmReserved = 0;
  187.   InsXTime(&tblah);
  188.   PrimeTime(&tblah,time);
  189. }
  190.  
  191. This didn't work, and I don't have a lot of time to figure out 
  192. why, so if anyone has any ideas I'm open to them.  Thanks in
  193. advance.  Reply through e-mail if possible.
  194.  
  195. =====================================================================
  196. Anthony Molinaro
  197. anthonym@ugcs.caltech.edu
  198.  
  199.  
  200.  
  201.  
  202. +++++++++++++++++++++++++++
  203.  
  204. >From Carl R. Osterwald <carl_osterwald@nrel.gov>
  205. Date: Fri, 21 Oct 1994 17:23:44 GMT
  206. Organization: National Renewable Energy Laboratory
  207.  
  208. In article <387t0n$3rr@gap.cco.caltech.edu> Anthony Molinaro,
  209. anthonym@puree.ugcs.caltech.edu writes:
  210. >Now, he tells me he needs a delay time smaller than one tick.  
  211. >I know that the time manager can do this but I have been 
  212. >unable to get it to work.  I guess my confusion arises in the
  213. >type declarations and getting all of the types to match for 
  214. >functions InsXTime(), PrimeTime(), and such.  The Inside 
  215.  
  216. Here is an example of a Time Manager task:
  217.  
  218. typedef struct
  219.     {
  220.         TMTask        tm_task;
  221.         long        A5;
  222.     } time_info;
  223.  
  224. Initialization:
  225.     timer_rec.tm_task.tmAddr = (TimerProcPtr)&time_task;
  226.     timer_rec.tm_task.tmWakeUp = 0;
  227.     timer_rec.tm_task.tmReserved = 0;
  228.     timer_rec.A5 = SetCurrentA5();
  229.     InsXTime( (QElemPtr)&timer_rec );
  230.     PrimeTime( (QElemPtr)timer_rec, period );  <<-- This starts the task
  231.  
  232. static void time_task (void)
  233.     {
  234.         time_info    *timer_rec;
  235.         long        current_A5;
  236.         
  237.         asm
  238.             {
  239.                 MOVE.L        A1,timer_rec
  240.                 MOVE.L        A5,current_A5
  241.             };
  242.         SetA5(timer_rec->A5);
  243.         PrimeTime( (QElemPtr)timer_rec, period );  <<-- This restarts
  244. the task
  245.         SetA5(current_A5);
  246.     }    // time_task
  247.  
  248. You can access your globals between the SetA5 calls.  Because the time
  249. task runs as an interrupt, it is best to minimize processing inside.  In
  250. your case, I would just set a global flag that is polled in the main
  251. event loop to see if it is tim;      //Restore D0
  252.    SetA0( gOldGNEFilter ); //Put next jGNEFilter in A0
  253.    
  254.    RestoreA4();
  255.  
  256.    asm{
  257.       Unlk     A6
  258.       Move.W   D0, 4(A7)   ;Set Function result on the stack
  259.       JMP      (A0)     ;Jump to the next jGNEFilter
  260.    }
  261.  
  262. }
  263.  
  264. Since a jGNEFilter has access to the actual event record that will be 
  265. returned to the application, the filter can alter the event.  The 
  266. most common thing to do is to 'cancel' an event by changing it to a 
  267. null event (Ex. theEvent->what = nullEvent).  In this case it should 
  268. also set the value in register D0 to False, or zero.
  269.  
  270. Here are some additional methods for an extension to get time 
  271. periodically:
  272.  
  273. If your extension needs more frequent or regular time then can be 
  274. provided by a jGNEFilter then you can install a VBL task or a time 
  275. manager task.  Since these run at interrupt time they cannot do 
  276. anything that could move or purge memory.  Other methods include 
  277. patching a trap that is called frequently, like SetPort.
  278.  
  279. A faceless Notification Manager request is another method to get 
  280. time.  This is a request that has all the fields in the notification 
  281. record set to NULL except the nmResp field that holds the address of 
  282. your routine to be executed.  Your notification response routine will 
  283. be called soon and will be able to move memory.  If necessary the 
  284. routine can reinstall itself.  This technique is useful for tasks 
  285. that need to be executed once or intermittently.  For those tasks 
  286. that need to be executed regularly use one of the other techniques.
  287.  
  288. You could of course have a faceless NM request that is installed by a 
  289. VBL task or a time manager task.  
  290.  
  291. Use of a faceless background application in concert with an extension 
  292. is yet another method to get time.  The fba would do its work on its 
  293. null events.
  294.  
  295. --
  296. [11] How should an INIT manage memory?
  297.  
  298. In general, at INIT time extensions will want to allocate memory in 
  299. the system heap.  If you are allocating pointers or handles, use the 
  300. SYS variants, like NewHandleSys() and NewPtrSys().  It is a common 
  301. error to forget this and then to wonder why the INIT crashes.  If you 
  302. call NewHandle at INIT time, the handle will be allocated in the 
  303. temporary heap allocated for your extension.  If your INIT attempts 
  304. to use it after INIT time the temporary heap will be long gone, along 
  305. with any handles or pointers that had been allocated in it.  Any 
  306. attempt to use handles or pointers that no longer exist are 
  307. predictably unpredictable :-) 
  308.  
  309. NewHandle and NewPtr will allocate their memory blocks in the system 
  310. heap if the zone has been set to the system heap, as shown in the 
  311. next paragraph.
  312.  
  313. If you need to read in resources you can ensure that they go into the 
  314. system heap with something like the following code:
  315.  
  316. THz   saveZone = GetZone();
  317.    SetZone( SystemZone() );
  318.    //read in resources
  319.    SetZone( saveZone );
  320.  
  321. You will of course need to detach the resources if they need to 
  322. remain in memory after your extension exits.  The resource file 
  323. containing your extension will be closed when your extension exits.
  324.  
  325. If you need to read resources into memory after INIT time you need to 
  326. decide which heap they should go into, either the application heap or 
  327. the system heap.  It's a bit hard to make a specific recommendation 
  328. on this but if the resource is something that the application is 
  329. expecting to be read in then it should go into the application heap.  
  330. This would include things like WIND resources in a trap patch to 
  331. GetNewWindow().  The problem of course is that the application heap 
  332. may not have enough room.  However, if the resources are private to 
  333. the extension then they should go into the system heap.
  334.  
  335. It should go without saying that you should always check the error 
  336. codes on memory allocating calls and resource manager calls.  If your 
  337. extension is doing something in response to a user action, say making 
  338. a network connection, then it is appropriate to report such errors.  
  339. In many cases however, your extension will simply do nothing in the 
  340. case of out of memory errors or missing resource errors.  It is best 
  341. to attempt to allocate all of these things at INIT time and if 
  342. unsuccessful to bail out then.
  343.  
  344. As mentioned above, MoveHHi doesn't work in the system heap.  If you 
  345. intend to allocate a handle that will remain locked for extended 
  346. periods, then call ResrvMem before allocating and locking the handle.  
  347. This will place the handle low in the system heap and help to prevent 
  348. heap fragmentation. 
  349.  
  350. Many toolbox calls are documented as not moving or purging memory and 
  351. as being safe to call at interrupt time.  If you are patching one of 
  352. these traps then you must preserve this property.  You are guaranteed 
  353. to cause other software to crash if you don't, and your users will 
  354. hate you (once they figure out that it's you).  Be aware that the 
  355. only memory manager routine safe to call under these circumstances is 
  356. BlockMove. Also be aware that it is unsafe to access an unlocked 
  357. handle at interrupt time.  It is possible that the memory manager is 
  358. in the midst of moving it from one place to another in the heap, and 
  359. the master pointer may not be updated yet.
  360.  
  361. --
  362. [12] How do I get my INIT to turn itself off?
  363.  
  364. An extension might want to turn itself off at INIT time based on its 
  365. preferences setting, or based on a key being pressed or the mouse 
  366. button being pressed, or due to an error during initialization.  
  367. Extensions usually show an icon with a red X through it in this case.  
  368. An extension might also want to turn itself off temporarily after 
  369. INIT time in response to its Control Panel.  For instance GateKeeper 
  370. has an on/off switch that turns off virus checking for a set time.
  371.  
  372. The strategy for temporarily turning off an extension is simply to 
  373. set a global flag and to check it from within the trap patches or 
  374. other parts of the extension.  If the flag is off then the trap patch 
  375. simply executes the previous trap.  It is generally unsafe to unpatch 
  376. or patch traps after INIT time from an extension.  The reason for 
  377. this is that if another extension patches the same trap after you 
  378. have, then it will be jumping to your patch when it has completed its 
  379. work.  If you have removed your patch then this calling chain will be 
  380. disrupted and bad things will happen.  Also, the Finder patches 
  381. various traps when it loads, which is after INIT time.  Disrupting 
  382. those patches would be a very bad thing.
  383.  
  384. If an extension determines at INIT time that it isn't going to stay 
  385. around then it shouldn't call DetachResource on itself.  It's best 
  386. that your extension determine that anything it's dependent on, such 
  387. as resources, specific system Managers, and sufficient memory, are 
  388. present *before* it starts to patch traps and install drivers, 
  389. jGNEFilters and so on.  It would be a very bad idea for an extension 
  390. to not detach itself after it had already patched a trap if the trap 
  391. patch resided in the extension.
  392.  
  393. Many extensions use a particular key press as a signal to indicate 
  394. that the user wants them not to run.  Of course the system uses the 
  395. shift key as a signal not to turn on any extensions so you can't use 
  396. that.  Some extensions use the option or command keys for this 
  397. purpose.  The problem with using those keys is that every time I 
  398. rebuild the desktop those extensions are needlessly inactivated.  I 
  399. recommend that the space bar be used for this purpose.  Here's some 
  400. sample code:
  401.  
  402.  Boolean
  403.  SpaceBarIsDown(void)
  404.  {
  405.    KeyMap      theKeys;
  406.  
  407.    GetKeys( theKeys );
  408.  
  409.    if ( theKeys[1] & 0x00000200 )//Check for spacebar
  410.       return TRUE;
  411.    else
  412.       return FALSE;
  413.  
  414.  }
  415.  
  416. --
  417. [13] How do I get my INIT to show it's icon like all the other cool 
  418. inits do?
  419.  
  420. This is easy.  There is code available that does this for you.  Get a 
  421. package written by Jim Walker called ShowIcon7 at:
  422. ftp://mac.archive.umich.edu/mac/development/source/showicon7.sit.hqx
  423.  
  424. You use it essentially as a plug-in.  Just pass in the icon's 
  425. resource ID and it does everything for you.  It also shows how to set 
  426. up an A5 world in an extension.  You might also take a look at Dair 
  427. Grant's Extension shell package.  This one shows how to do animated 
  428. icons.
  429.  
  430. If your extension decides that it can't install itself then it passes 
  431. the resource ID of an icon that has a red X through it to the 
  432. showicon7 code resource.
  433.  
  434. Some extensions include the ShowIcon code within their own code 
  435. resources.  This code is only about 1K but it seems pointless to me 
  436. for this code to sit in the system heap when it doesn't have to be.  
  437. Use it as a plug-in for your extensions.
  438.  
  439. --
  440. [14] How do I show a dialog from my INIT?
  441.  
  442. First of all, I hate windows of any kind during the startup process.  
  443. If all you want to do is show an alert then use the Notification 
  444. Manager.  Your alert will show up when the Finder starts but the user 
  445. will see it and will get whatever message you need to send.  
  446.  
  447. The problem I have with windows at INIT time is that they slow down 
  448. this process and require user interactivity in a process that 
  449. shouldn't do so.  Consider the computer that is on 24 hours a day 
  450. doing something important unattended.  The power goes off and when it 
  451. comes back on the machine reboots.  The user returns several hours 
  452. later to find that the machine is still in the middle of its startup 
  453. because your alert is waiting for a response.  Consider also the 
  454. hapless INIT writer who has to reboot his machine 20 times a day.  
  455. Your INIT will not last long on my, um, his machine.
  456.  
  457. One additional annoyance is that you need to call InitWindows to show 
  458. your window and this erases all the nice INIT icons on the screen.  I 
  459. hate that.
  460.  
  461. Here are a few possible alternatives.  
  462.  
  463. * Play a sound or use the Speech Manager to communicate the 
  464. information.  
  465.  
  466. * Show a different icon during startup to indicate an error.  An icon 
  467. with a red X through it is one way to do this.  You could also use 
  468. animated icons.
  469.  
  470. * If you must put up an alert then use a timer so that the alert goes 
  471. away by itself, even if the OK button isn't clicked.
  472.  
  473. * If you need to interact with the user to get some information, say 
  474. a password for a network connection, then do this once and save the 
  475. results in a preferences file.  Provide a Control Panel to change the 
  476. information.  Think of Control Panels as the interface for 
  477. extensions.
  478.  
  479. * Store descriptions of any errors that occur in a preferences file.  
  480. Have the Control Panel display this information.  Remember to clear 
  481. this information on each restart and to indicate to the user by sound 
  482. or icon that an error has occurred.
  483.  
  484. * If you need to communicate error information to the user after INIT 
  485. time then you should definitely use the Notification Manager.  For 
  486. example, MacSLIP uses the NM to show an alert indicating that the 
  487. carrier has been lost.
  488.  
  489. If you still want to show a dialog at INIT time then you need to set 
  490. up an A5 world first.  The ShowIcon7 code mentioned above shows how 
  491. to do this.  Also see the Tech Note 'Stand-Alone Code' (#256) for an 
  492. explanation and sample code for this and 'Giving the (Desk)Hook to 
  493. INITs' (247) discusses a bug that can appear when showing windows 
  494. from extensions.
  495. ftp://ftp.apple.com/dts/mac/tn/operating.system.os/os-02-deskhook-
  496. and-init.hqx
  497.  
  498. If you do use the Notification Manager from an extension to indicate 
  499. that the extension couldn't load you should use a self-disposing 
  500. Notification request.  There are several strategies for doing this.  
  501. I have some code samples for this that will be (have been?) posted to 
  502. alt.sources.mac soon.
  503.  
  504. --
  505. [15] How do I maintain compatibility with future systems?
  506.  
  507. This is tough, and the short answer is that you probably don't.  
  508. You'll notice that Apple comes out with new versions of its 
  509. extensions with each revision of the system.  Apple's extensions also 
  510. eventually disappear as their functionality is rolled into the 
  511. system.  In all likelihood you'll have to come out with new versions 
  512. of your extensions as new versions of the system come out as well.
  513.  
  514. Having said all that, there are things you can do to minimize this 
  515. problem.  Here are a few suggestions:
  516.  
  517. * Minimize your reliance on undocumented features of the system.
  518.  
  519. * Minimize your reliance on low memory globals.  Use the Universal 
  520. Header access 'functions' for accessing the low memory globals if 
  521. necessary.
  522.  
  523. * Use system features like Gestalt, the Process Manager, and the 
  524. Notification Manager to get information about the system, and to 
  525. communicate with the user.
  526.  
  527. * Try to patch as few traps as possible and use non-patching methods 
  528. whenever possible (e.g., use a jGNEFilter instead of patching 
  529. WaitNextEvent; the filter is more likely to remain compatible than 
  530. your patch).  
  531.  
  532. * Don't use self-modifying code.  Self-modifying code changes the 
  533. instructions from what they were compiled as, to something else, at 
  534. run-time.  The classic example is to change the address in a JMP 
  535. instruction at run-time so that it jumps to the address of the 
  536. previous trap.  This may seem faster than using a global variable but 
  537. it is only slightly faster.  It is harder to write, debug, and 
  538. maintain self-modifying code, and it is definitely more likely to 
  539. break with new system releases.  If you do use self-modifying code, 
  540. remember to flush the cache.  See the tech note 'Cache As Cache Can' 
  541. (#261) for more information on that subject.
  542.  
  543. * Use the Universal Headers for writing your extensions.  This will 
  544. help to ease the transition when it comes.
  545.  
  546. --
  547. [16] Any tips for INIT writing?
  548.  
  549. You may not want your INIT to actually do anything until after INIT 
  550. time.  You can find the end of INIT time if you have a jGNEFilter 
  551. installed when the first null event occurs.  The Notification Manager 
  552. doesn't usually start processing requests until INIT time is over so 
  553. posting a faceless notification request is another method to find the 
  554. end of INIT time (probably the best if you don't need a jGNEFilter 
  555. for something else).  You can also patch Launch to find the end of 
  556. INIT time but this is trickier.
  557.  
  558. Unfortunately some extension writers do put up windows during INIT 
  559. time.  Because of this it's possible that events will occur before 
  560. INIT time is over.  To fail-safe the above approaches you also need 
  561. to check for the presence of the Process Manager with a Gestalt call.  
  562. The Process Manager isn't available until after INIT time.  If 
  563. Gestalt reports that the Process Manager is not available then you 
  564. need to reinstall your NM request, or simply wait for another event 
  565. to be reported to your jGNEFilter when the Process Manager is 
  566. available.
  567.  
  568. Here are some utility routines that can reduce the need for 68K 
  569. assembler in your extensions:
  570.  
  571. pascal void SetA0( void* ) = { 0x205F };
  572. pascal void SetA1( void* ) = { 0x225F };
  573. void *   GetA0( void ) = { 0x2008 };
  574. void *   GetA7( void ) = { 0x200F };
  575.  
  576.  
  577. - -------------------------------------------------------------------
  578.  
  579. Trap Patches:
  580.  
  581. --
  582. [17] What exactly is a trap patch?
  583.  
  584. A trap patch is a method for changing the functionality of a trap.  
  585. The addresses of all the traps are maintained in the two trap 
  586. dispatch tables.  By using the routine NSetTrapAddress and friends 
  587. you can change the address of a particular trap to code that you 
  588. provide.  When this is done at INIT time, all calls to the patched 
  589. trap from all applications will go to your code, which in most cases 
  590. will do something and then call through the existing trap in the 
  591. ROMs.  Be warned that the Finder patches some traps when it starts up 
  592. in a way that prevents previously-installed patches from executing.  
  593.  
  594. I recommend that you read the descriptions of the trap dispatch 
  595. mechanism in the 'Using Assembly Language' chapters in IM I and IV 
  596. and also in the 'Trap Manager' chapter in NIM Operating System 
  597. Utilities.
  598.  
  599. Traps come in several types based on their parameter passing 
  600. conventions.  Most toolbox traps use pascal calling conventions, 
  601. which means that all parameters are passed on the stack and the 
  602. return value, if any, is placed on the stack.  
  603.  
  604. Some traps use register-based calling conventions.  In these traps 
  605. the parameters are passed in registers and the return value is 
  606. returned in a register, usually D0.  For example all the Memory 
  607. Manager traps are register-based and the File Manager traps are also 
  608. register-based.  
  609.  
  610. Some traps are selector-based.  There are only so many spots in the 
  611. trap-dispatch tables.  In order to preserve space in these tables 
  612. selector-based traps have been developed.  In these traps a single 
  613. trap serves as the front end for a number of system routines.  The 
  614. parameters of these traps are passed in the usual manner, either on 
  615. the stack or in registers, and a selector is also passed, usually in 
  616. a register.  When the trap is called it checks the selector and then 
  617. dispatches to the appropriate routine.  Patching each of these types 
  618. of traps involves different mechanisms.  We'll look at samples of 
  619. each one.
  620.  
  621. Patching traps on the PowerMac is a bit different than on the 68K 
  622. Macs.  Most of the discussion here is aimed at patching traps on the 
  623. 68K Macs.  Hopefully I'll learn some more about this subject soon and 
  624. there will be some better info here on patching traps on the 
  625. PowerMac.
  626.  
  627. --
  628. [18] What's the difference between a head patch and a tail patch?
  629.  
  630. It is most common to add some functionality to a trap when patching 
  631. it rather than just replacing the existing trap.  For instance I've 
  632. written an extension that speaks the text in alerts by using the 
  633. Speech Manager.  This works by patching Alert and friends.  When 
  634. Alert is called the patch gets the text that appears in the alert and 
  635. passes it to the Speech Manager.  The patch then calls the existing 
  636. Alert trap that is in the ROMs.  A patch that works in this way is 
  637. called a head patch; it does its business and then it calls the 
  638. previous trap.
  639.  
  640. A tail patch is a bit different.  A virus-checking program might want 
  641. to patch GetResource and then examine the resource that was read in 
  642. to see if it contains a virus.  In order to do this the patch must 
  643. first call the existing trap and then do its processing, and finally 
  644. return to the application.  This is a tail patch because some 
  645. processing occurs after the existing trap is called.  In order for a 
  646. patch to be a head patch you must use a jmp instruction to jump to 
  647. the previous trap.  If you use a jsr or a C function pointer to jump 
  648. to the previous trap you have a tail patch.
  649.  
  650. The reason that this head and tail patch business has been so 
  651. important in the past is because of an Apple invention called the 
  652. come-from patch.  Patches were invented, of course, so that Apple 
  653. could fix bugs in the ROMs and could update the routines in the ROMs 
  654. with software.  This is why you can run system 7 on a Mac Plus, whose 
  655. ROMs are obviously missing most of the additions made to the toolbox 
  656. in recent years.  
  657.  
  658. Certain ROM routines are particularly large so it is inconvenient to 
  659. patch them if they have bugs in them.  To get around this problem the 
  660. Apple programmers searched for smaller routines that are called from 
  661. the large buggy routines and placed patches in the smaller routines.  
  662. These patches check the return address on the stack.  If it is the 
  663. address of the buggy routine then a fix is applied.  If not then they 
  664. just go on as usual.  The patches to these smaller routines are known 
  665. as come-from patches.  If you tail patch one of these and then call 
  666. the existing come-from patch, the return address on the stack will be 
  667. in your patch and not the buggy routine that called you.  In this 
  668. case the come-from patch will not apply its fix and your system will 
  669. crash.  
  670.  
  671. The good news is that as of system 7 it is safe to apply tail 
  672. patches.  The come-from patches still exist in system software, but 
  673. NGetTrapAddress has been modified to return an address that is safe 
  674. to use when applying tail-patches.  However, if you wish your 
  675. extension to run in System 6 then tail-patches are not allowed.  This 
  676. is documented in the Trap Manager chapter in NIM: OS Utilities.
  677.  
  678. If you absolutely positively need a tail patch in System 6 then the 
  679. following logic may apply: (Just don't tell anyone that I told you 
  680. this :-)  Apple is not releasing any new versions of System 6 so no 
  681. new come-from patches will be forthcoming for System 6.  If you do 
  682. careful testing of the traps you wish to tail-patch you will probably 
  683. be OK.  In general traps not called from the ROMs, like Alert and 
  684. MenuKey, will not contain come-from patches.
  685.  
  686. One final thing: In system 7 it is safe to apply tail-patches to all 
  687. traps except FrontWindow.
  688.  
  689. --
  690. [19] How do I patch a trap?
  691.  
  692. Here is some sample code for a head patch of Alert, a stack-based 
  693. trap:
  694.  
  695. TrapPtr  gOldAlertTrapAddress;
  696.  
  697. /****InstallPatch***************************************************/
  698.  
  699. void 
  700. InstallPatch (void)
  701. {
  702.    gOldAlertTrapAddress = GetToolTrapAddress( _Alert );
  703.    SetToolTrapAddress( (long) AlertPatch, _Alert );
  704. }
  705.  
  706. /****AlertPatch***************************************************/
  707.  
  708. pascal void 
  709. AlertPatch( short alertID, ProcPtr filterProcPtr )
  710. {
  711.    SetUpA4();
  712.  
  713.    MyAlert( alertID) ;  //Do our thing
  714.  
  715.    //store the correct alert addr
  716.    //in A0 while we can still access globals via A4
  717.  
  718.    asm   { move.l gOldAlertTrapAddress, A0 }
  719.  
  720.    RestoreA4();
  721.    
  722.    asm   {
  723.          unlk     A6 //match the link generated by C
  724.          jmp      (A0)  //jump to _Alert
  725.       }
  726. }
  727.  
  728. There are a number of details to note here.  This patch is of course 
  729. part of a code resource that is loaded at INIT time and detached as 
  730. described in an earlier section.  The routine InstallPatch must be 
  731. called at INIT time.  
  732.  
  733. The routines GetToolTrapAddress and SetToolTrapAddress allow you to 
  734. get and set the addresses of Tool Traps.  The similar routines 
  735. GetOSTrapAddress and SetOSTrapAddress allow you to manipulate the 
  736. addresses of OS traps.  The routines NGetTrapAddress and 
  737. NSetTrapAddress allow you to manipulate the addresses of either, 
  738. although they call glue code.  I recommend that you use the 
  739. GetXTrapAddress and SetXTrapAddress calls.  There are two obsolete 
  740. calls: GetTrapAddress and SetTrapAddress.  Don't use them.
  741.  
  742. The prototype for this patch is declared as 'pascal void' while the 
  743. prototype for Alert is 'pascal short'.  Because this is a head patch 
  744. it will not be returning a result; the result will be returned from 
  745. the real Alert trap.  The pascal keyword is used to indicate pascal 
  746. calling conventions.  It is not strictly required in all cases but 
  747. does no harm.  
  748.  
  749. The Think C routines SetUpA4 and RestoreA4 are called to allow access 
  750. to global variables by A4 addressing.  In this case 
  751. gOldAlertTrapAddress is the only global variable we are addressing, 
  752. unless any are used inside MyAlert.  Note that this variable is moved 
  753. to A0 while access to global variables is still available.  In some 
  754. cases one might move a global variable to a local variable, which 
  755. doesn't rely on A4 addressing.  A4 could then be restored and the old 
  756. trap address could be loaded into A0 later in the code. 
  757.  
  758. Because there is a parameter list the compiler generates a Link A6 
  759. instruction at the start of this function.  In order to restore the 
  760. stack a matching Unlk A6 must be placed at the end of the function.  
  761. Since we are exiting by the jmp (A0) we must insert the Unlk A6 
  762. ourselves.  The compiler does generate an Unlk A6 and an RTS at the 
  763. end of this function, but they will never be executed.  The presence 
  764. of the Link A6 instruction is dependent on the particular compiler 
  765. you use and on its rules for generating a stack frame.  It is a good 
  766. idea to disassemble the code for your trap patches to see whether a 
  767. stack frame has been generated in order to determine if you need to 
  768. insert the Unlk A6 instruction.  If you don't match the Link A6 with 
  769. an Unlk A6 the stack will be screwed up.
  770.  
  771. It is essential that the stack look exactly the same on exit from a 
  772. head patch as it does on entry.  If not you will surely crash.  (If 
  773. you had good reason you could modify the value of a parameter on the 
  774. stack, but that's another story.)  This patch saves and restores A4 
  775. but does modify A0 and A1 (SetUpA4 uses A1).  In general, with head 
  776. patches of stack-based traps you can modify A0, A1, D0, D1, and D2, 
  777. but not any other registers.  You may need to look at the 
  778. disassembled code to be sure that all your registers are properly 
  779. saved and restored.  
  780.  
  781. The design of the patch as shown here, with the patch code calling a 
  782. separate function to perform the actual functionality of the patch is 
  783. a good design to follow with all but the simplest of patches.
  784.  
  785. You might think that you need to call StripAddress on the address of 
  786. the patch routine before passing this address to SetToolTrapAddress.  
  787. This is not necessary unless the address is actually a handle.  If 
  788. you were to load a code resource and pass its entry point to 
  789. SetToolTrapAddress then it would need to be stripped.
  790.  
  791. -- 
  792. Brian  Stern  :-{)}
  793. Toolbox commando and Menu bard
  794. Jaeger@fquest.com
  795.  
  796. ---------------------------
  797.  
  798. >From Jaeger@fquest.com (Brian Stern)
  799. Subject: INIT Writing FAQ [3-3]
  800. Date: 28 Oct 1994 00:44:27 GMT
  801. Organization: The University of Texas at Austin, Austin, Texas
  802.  
  803. --
  804. [20] How do I patch a register-based trap?
  805.  
  806. Here is the code for a sample register-based trap patch:
  807.  
  808. TrapPtr     gMountVolAddress;
  809.  
  810. /****InstallPatch**************************************************/
  811.  
  812. void 
  813. InstallPatch(void)
  814. {
  815.    gMountVolAddress =  GetOSTrapAddress( _MountVol );
  816.    SetOSTrapAddress( (long) MountVolPatch, _MountVol );
  817. }
  818.  
  819. /****MountVolPatch**************************************************
  820.  
  821. This is a register-based trap that has A0 set to point to its 
  822. parameter
  823. block on entry.  The  prototype for MountVol is:
  824.  
  825.    pascal OSErr PBMountVol( ParmBlkPtr paramBlock )
  826.  
  827. This patch beeps when a floppy or CD-ROM is inserted or when a 
  828. harddrive is mounted by the Finder.
  829.  
  830. *******************************************************************/
  831.  
  832. pascal void 
  833. MountVolPatch(void)
  834. {
  835. //Save some registers
  836. //Save A0 since it's trashed by SetUpA4
  837. //D1 contains the trap word
  838.  
  839.    asm   {  movem.l  a0/d0-d1, -(sp)      }
  840.  
  841.    SetUpA4();     //Allow access to global variables
  842.  
  843.    SysBeep( 5 );  //The guts of our head patch
  844.    
  845.    //store the correct MountVol addr
  846.    //in A1 while we can still access globals via A4
  847.    asm   {  move.l   gMountVolAddress, A1 }
  848.  
  849.    RestoreA4();   //Restore previous value in A4
  850.    
  851.    asm   {              //Restore the registers
  852.          movem.l  (sp)+, a0/d0-d1
  853.          jmp      (A1)     //jump to _MountVol
  854.       }
  855.  
  856. }
  857.  
  858. This head patch is similar in structure to the patch to Alert with a 
  859. few differences.  The prototype uses no parameters and has no return 
  860. value. The single parameter is passed through A0.  This patch doesn't 
  861. do anything with this value but it could be moved to a local variable 
  862. and then used to reference the fields in the parameter block if 
  863. desired.  Access to global variables is by the same A4 mechanism as 
  864. in the Alert patch.  Note that _MountVol is an OS trap so 
  865. GetOSTrapAddress and SetOSTrapAddress are used to set up the patch.  
  866.  
  867. Since A0 is used to pass the parameter to this trap we jump to the 
  868. real _MountVol trap through A1.  
  869.  
  870. Obviously A0 must be saved and restored in this patch. OS traps 
  871. expect to find the trap word in D1 so it must be saved and restored 
  872. as well.  Three registers, A0, D0, and D1, are saved onto the stack 
  873. with the movem instruction, and restored at the end of the patch.  
  874.  
  875. Think C doesn't generate a 'Link A6' at the start of this function 
  876. because there are no parameters and no local variables.  Because of 
  877. this no 'Unlk A6' is needed at the end of the function.
  878.  
  879. --
  880. [21] Can you show me an example tail patch?
  881.  
  882. Here is another example of a patch to a register-based trap.  This 
  883. sample is a tail patch and is dependent on the CodeWarrior 
  884. environment.  Because CW allows you to specify that parameters are 
  885. passed in registers this trap patch requires no assembly.
  886.  
  887. extern pascal OSErr (*Old_MountVol)( ParmBlkPtr pb : __A0 ) : __D0;
  888.  
  889. pascal OSErr My_MountVol( ParmBlkPtr pb : __A0 ) : __D0
  890. {
  891.    OSErr    err;
  892.    long     saveA4 = SetCurrentA4();
  893.  
  894.    err = Old_MountVol( pb );
  895.    DoSomthingFunc();
  896.  
  897.    SetA4( saveA4 );
  898.    return err;
  899. }
  900.  
  901. --
  902. [22] How do I patch a selector-based trap?
  903.  
  904. Here is a sample patch to PrGlue.  This trap is the front end for all 
  905. the Printing Manager routines.  Its selector is pushed on the stack
  906.  
  907. typedef struct 
  908. {
  909.    long     Selector;
  910.    THPrint     hPrint;
  911. } PrJobDialogStack;
  912.  
  913. TrapPtr     PrGlueAddress;
  914.  
  915. /****InstallPatch****************************************************
  916. /
  917.  
  918. void 
  919. InstallPatch(void)
  920. {
  921.    PrGlueAddress = GetToolTrapAddress( _PrGlue );
  922.    SetToolTrapAddress( (long) PrGluePatch, _PrGlue );
  923. }
  924.  
  925. /****PrGluePatch****************************************************
  926.  
  927. This is a stack-based trap with a long word selector also pushed 
  928. onto the stack.  On entry the selector is at 4(A7).  The return 
  929. address is at 0(A7).  After the 'Link A6' the selector is at 12(A7).
  930.  
  931. *******************************************************************/
  932.  
  933. #define kSelectorOffset 12
  934. #define kPrJobDialogSelector 0x32040488
  935.  
  936. pascal void 
  937. PrGluePatch(void)
  938. {
  939.    PrJobDialogStack  *StackPtr;
  940.  
  941.    //Get address of the stack frame
  942.    //and save it in a local variable
  943.  
  944.    asm   { 
  945.          lea    kSelectorOffset(A7), A0
  946.          move.l A0, StackPtr
  947.       }
  948.  
  949.    SetUpA4();     //Allow access to global variables
  950.  
  951.    //Check the selector
  952.    if ( StackPtr->Selector == kPrJobDialogSelector )
  953.    {
  954.       SysBeep( 5 );
  955.  
  956.       //Pass hPrint to our function to do something
  957.       DoSomethingFunc( StackPtr->hPrint );
  958.    }
  959.  
  960.    //Store the correct PrGlue addr
  961.    //in A0 while can still access globals via A4
  962.    asm   { move.l PrGlueAddress, A0 }           
  963.             
  964.    RestoreA4();   //Restore previous value in A4
  965.    
  966.    asm   {
  967.          unlk     A6 //match C's Link A6
  968.          jmp      (A0)  //jump to _PrGlue
  969.       }
  970.  
  971. }
  972.  
  973. In order to access the selector and the parameters for PrGlue we use 
  974. a pointer to a struct.  Once the pointer is initialized correctly we 
  975. can access the selector and any parameters from C easily.
  976.  
  977. According to NIM: PPC System Software it is not safe to patch 
  978. selector-based traps with PPC native code.  All patches of selector-
  979. based traps on the PowerMac should be written in 68K code.
  980.  
  981. --
  982. [23] How do I patch a trap on the PPC?
  983.  
  984. See NIM 'PowerPC System Software' for a more complete discussion.  
  985. There is also a new book by Tom Thomson called 'Power Macintosh 
  986. Programming Starter Kit' that has examples of how to patch traps on 
  987. the PowerMac.  
  988.  
  989. Patching traps on the PowerMac is similar to patching on the 68K 
  990. architecture.  Of course you must generate a UniversalProcPtr for 
  991. each of your patches in the system heap, and these are then passed to 
  992. the SetXTrapAddress routines.  Since code fragments have their own 
  993. globals the use of A4 or A5-based mechanisms for accessing global 
  994. variables isn't needed.  In order to call the previous trap you need 
  995. to call CallUniversalProc or CallOSTrapUniversalProc and return its 
  996. result from your patch.  As a result all patches on the PowerMac are 
  997. tail patches.
  998.  
  999. You may find an application called 'Traps Check' useful.  This app 
  1000. supplies a report about all the traps on a Powermac, indicating 
  1001. whether each trap is emulated or native.  Another way to do this is 
  1002. to drop into MacsBug and disassemble from the address of the trap 
  1003. you're interested in (e.g., 'il CopyBits' ).  For traps that are 
  1004. native you'll see a routine descriptor that begins with the 
  1005. MixedModeMagic trap (AAFE). This of course won't tell you if the trap 
  1006. has been patched.  You can identify a patch by whether it's in RAM or 
  1007. ROM, from its address.  Determining whether a patched trap is PPC 
  1008. native or not may take some additioinal sleuthing. You can find Traps 
  1009. Check at:  ftp://sumex-aim.stanford.edu/info-mac/dev/traps-check-
  1010. 10.hqx
  1011.  
  1012. Here is a sample PowerMac trap patch for GetResource:
  1013.  
  1014. UniversalProcPtr gGetResourceUPP;
  1015. UniversalProcPtr gGetResourcePatchUPP;
  1016.  
  1017. /****InstallPatch**************************************************/
  1018.  
  1019. void
  1020. InstallPatch(void)
  1021. {
  1022.    gGetResourceUPP = GetToolTrapAddress( _GetResource );
  1023.  
  1024.    gGetResourcePatchUPP = 
  1025.       NewRoutineDescriptor( (ProcPtr) GetResourcePatch,  
  1026.       kPascalStackBased, GetCurrentISA() );
  1027.  
  1028.    SetToolTrapAddress( gGetResourcePatchUPP, _GetResource );
  1029.  
  1030. }
  1031.  
  1032.  
  1033. /****GetResourcePatch*********************************************/
  1034.  
  1035. Handle 
  1036. GetResourcePatch( ResType theType, short theID )
  1037. {
  1038.    Handle   result;
  1039.  
  1040. //We don't need no 'DUMB' resources
  1041.    if ( theType == 'DUMB' )
  1042.       result = NULL;
  1043.    else
  1044.       result = (Handle) CallUniversalProc( gGetResourceUPP,
  1045.             kGetResourceProcInfo, theType, theID );
  1046.    
  1047.    return result;
  1048.  
  1049. }
  1050.  
  1051. --
  1052. [24] Can I write a fat trap?
  1053.  
  1054. //Under construction
  1055.  
  1056. --
  1057. [25] Tips?
  1058.  
  1059. If your patch isn't called you may have guessed wrong on whether it's 
  1060. a ToolTrap or an OSTrap.  The high bit of the second byte of the trap 
  1061. word is set for ToolTraps.  The following function can be used to get 
  1062. the correct trap address for both ToolTraps and OSTraps.
  1063.  
  1064. pascal void * GetCurrentTrapAddress( unsigned short trapWord )
  1065. {
  1066.    if ( trapWord & 0x0800 )
  1067.       return GetToolTrapAddress ( trapWord & 0x07FF );
  1068.    else
  1069.       return GetOSTrapAddress ( trapWord & 0x07FF );
  1070. }
  1071.  
  1072.  
  1073. If the machine crashes after leaving your patch you have probably 
  1074. munged the stack or not saved and restored all the registers that you 
  1075. must.
  1076.  
  1077. The Finder patches a number of traps when it loads in a way that 
  1078. prevents earlier trap patches from functioning.  If your patch 
  1079. doesn't appear to be called it may be one of these patches.
  1080.  
  1081. --
  1082. [26] What other sources of information are available?
  1083.  
  1084. Knaster 'How to Write Macintosh Software'
  1085. Knaster and Rollin, 'Macintosh Programming Secrets'.  These books on 
  1086. Mac programming has some excellent info on trap patching.
  1087.  
  1088. Tom Thomson 'Power Macintosh Programming Starter Kit' This book has 
  1089. some example code for writing trap patches and extensions on the 
  1090. PowerMac.
  1091.  
  1092. The Extension Shell package at:
  1093. ftp://sumex-aim.stanford.edu/info-mac/dev/src/extension-shell-13.hqx
  1094. Dair's email address has changed to: dair.grant@ucl.ac.uk.
  1095.  
  1096. Usenet Macintosh Programmers Guide
  1097. ftp://sumex-aim.stanford.edu/info-mac/dev/info/usenet-mac-prog-guide-
  1098. msw.hqx
  1099.  
  1100. All of the Apple Tech Notes have been made available on Apple's web 
  1101. server:   http://www.info.apple.com/dev/technotes/Main.html
  1102.  
  1103. -- 
  1104. Brian  Stern  :-{)}
  1105. Toolbox commando and Menu bard
  1106. Jaeger@fquest.com
  1107.  
  1108. ---------------------------
  1109.  
  1110. >From shawnl@andyne.on.ca (Dave Charlesworth)
  1111. Subject: Linking 68k object files to PPC program
  1112. Date: Thu, 27 Oct 1994 19:26:03 GMT
  1113. Organization: Andyne Computing
  1114.  
  1115. I want to link some third party code to a PowerPC program.  Can someone
  1116. point me to documentation on how to make this work?
  1117.  
  1118. I don't have source for the third party stuff.  I'm using MPW (ETO 15)
  1119. cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
  1120. "PowerPC System Software".  I haven't been able to find anything in it
  1121. or in the ETO documentation, but it must be somewhere!
  1122.  
  1123. Thanks.
  1124.  
  1125. Shawn Leclaire
  1126.  
  1127. +++++++++++++++++++++++++++
  1128.  
  1129. >From zellers@pokey.basilsoft.com (Steve Zellers)
  1130. Date: Fri, 28 Oct 1994 20:52:49 -0800
  1131. Organization: BasilSoft, Inc.
  1132.  
  1133. In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
  1134. Charlesworth) wrote:
  1135.  
  1136. > I want to link some third party code to a PowerPC program.  Can someone
  1137. > point me to documentation on how to make this work?
  1138.  
  1139. Assuming you mean that the third party code is 68k, you can't.  You'll
  1140. have to write a stub code resource that re-exports all the symbols you
  1141. need through a paramblock as some sort using route descriptors.
  1142.  
  1143. --smz
  1144.  
  1145. +++++++++++++++++++++++++++
  1146.  
  1147. >From wdh@fresh.com (Bill Hofmann)
  1148. Date: Sat, 29 Oct 1994 18:27:36 GMT
  1149. Organization: Fresh Software
  1150.  
  1151. In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
  1152. Charlesworth) wrote:
  1153.  
  1154. > I want to link some third party code to a PowerPC program.  Can someone
  1155. > point me to documentation on how to make this work?
  1156. > I don't have source for the third party stuff.  I'm using MPW (ETO 15)
  1157. > cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
  1158. > "PowerPC System Software".  I haven't been able to find anything in it
  1159. > or in the ETO documentation, but it must be somewhere!
  1160. Nope, not really.  Maybe some of the MacTech articles have mentioned it.
  1161. But what you have to do is:
  1162.     * find out which routines *you* call in the library
  1163.     * write some 68k code that wraps the library in a way that you can
  1164.       call it: either use a selector-based approach (ie, if message==1,
  1165.       call function 1, etc) or make a routine that returns a table of 
  1166.       procptrs
  1167.     * compile/link the wrapper with the library
  1168.     * create proc infos and stub code to call your 68k wrapper in your
  1169.       PowerPC program
  1170.     * debug :->
  1171.  
  1172. Or, yell at the third party until they produce a PowerPC version (shared
  1173. library, or whatever).
  1174.  
  1175. -Bill
  1176.  
  1177. -- 
  1178. Bill Hofmann                                  wdh@fresh.com
  1179. Fresh Software and Instructional Design       voice: +1 510 524 0852
  1180. 1640 San Pablo Ave #C, Berkeley CA 94702 USA  fax:   +1 510 524 0853
  1181.  
  1182. ---------------------------
  1183.  
  1184. >From rjkmehta@bu.edu (Ravi Mehta)
  1185. Subject: Network Programming
  1186. Date: 19 Oct 1994 16:20:21 GMT
  1187. Organization: Boston University
  1188.  
  1189. I want to write some networkable software, but am completely new to network
  1190. programming.  Besdies IM: Networking ( which I will pickup ) is there
  1191. anything else that would help?  Will IM: Networking discuss programming
  1192. for BOTH AppleTalk and Ethernet?  If not, what would be a good
  1193. source for learning how to write Ethernet and AppleTalk compatible software.
  1194.  
  1195. Thanks in advance.
  1196.  
  1197. Ravi J. K. Mehta
  1198. Terminal Sunset Software
  1199.  
  1200.  
  1201. +++++++++++++++++++++++++++
  1202.  
  1203. >From andym96@aol.com (AndyM96)
  1204. Date: 20 Oct 1994 01:13:05 -0400
  1205. Organization: America Online, Inc. (1-800-827-6364)
  1206.  
  1207. In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
  1208.  
  1209. <<
  1210. Will IM: Networking discuss programming
  1211. for BOTH AppleTalk and Ethernet?  If not, what would be a good
  1212. source for learning how to write Ethernet and AppleTalk compatible
  1213. software.>>
  1214. yes, IM networking  discusses how to do that. Also, a good book is
  1215. "Programming with AppleTalk" by Michael Peirce -code samples are in
  1216. Pascal, though, but it is a thorough and detailed description of how
  1217. AppleTalk protocols work & how to use 'em. 
  1218. BTW, if you dicover a code sample how to write a requester-responder pair
  1219. using ATP  in C, <<PLEASE>> e-mail me  @ andym96@aol.com -I've been trying
  1220. to get this info for a couple of weeks now with no avail.
  1221. Andy
  1222.  
  1223. +++++++++++++++++++++++++++
  1224.  
  1225. >From ntuck@muddcs.cs.hmc.edu (Nathan D. Tuck)
  1226. Date: 20 Oct 1994 20:02:38 GMT
  1227. Organization: Harvey Mudd College, Claremont CA
  1228.  
  1229.  
  1230. >In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
  1231. >
  1232.  
  1233. >Will IM: Networking discuss programming
  1234. >for BOTH AppleTalk and Ethernet?  If not, what would be a good
  1235. >source for learning how to write Ethernet and AppleTalk compatible
  1236. >software.>>
  1237.  
  1238. For both AppleTalk and Ethernet?  AppleTalk is a software protocol while
  1239. Ethernet is the physical format that AppleTalk runs over.  If you mean
  1240. LocalTalk and Ethernet, the two should be equivalent so far as ATP
  1241. API's are concerned.  If you mean to run transparantly over different
  1242. protocol stacks such as ATP and IPX/SPX or TCP/IP, that is another
  1243. question entirely.
  1244.  
  1245. Nate
  1246. ntuck@hmc.edu
  1247.  
  1248.  
  1249.  
  1250. +++++++++++++++++++++++++++
  1251.  
  1252. >From Yorick_Ph*nix,MacTel_Iconex@metro.mactel.org (Yorick
  1253. Ph*nix,MacTel_Iconex)
  1254. Date: 29 Oct 1994 02:48:38 GMT
  1255. Organization: MacTel Metro BBS, London, England.
  1256.  
  1257. Ravi
  1258.  
  1259. > I want to write some networkable software, but am completely new to
  1260. > network programming.  Besdies IM: Networking ( which I will pickup )
  1261. > is there anything else that would help?
  1262.  
  1263. There is a very good book called something like Introduction to AppleTalk
  1264. Programming - I have a copy at the office and I learnt all my Network
  1265. Programming from it. It is possibly published by Addison-Wesley and is one in
  1266. a series where Scott Knaster is the Series Editor.
  1267.  
  1268. AppleTalk programming is what you should be doing (ATP, NBP, ADSP, PAP, etc)
  1269. whereas LocalTalk and EtherNet are the phsyical mediums over which the
  1270. network data travels - you shouldnt need to get involved at this level or
  1271. even know which phsyical medium your program is dealing with.
  1272.  
  1273. Yorick
  1274.  
  1275. - sent via an evaluation copy of BulkRate (unregistered).
  1276.  
  1277. --
  1278. ****************************************************************************
  1279.               MacTel Metro - Europes largest Mac specific BBS
  1280.   The views expressed in this posting those of the individual author only.
  1281.                     Send mail to this user at either :-
  1282. INTERNET:User_Name@metro.mactel.org          [use underline]  between first
  1283.  FIDONET:User.Name@f202.n254.z2.fidonet.org  [use fullstop ]  & last names
  1284. ****************************************************************************
  1285.  
  1286. ---------------------------
  1287.  
  1288. >From walkerj@math.scarolina.edu (James W. Walker)
  1289. Subject: Stuck in SyncWait again
  1290. Date: Sat, 15 Oct 1994 21:39:18 -0500
  1291. Organization: Dept. of Mathematics, Univ. of South Carolina
  1292.  
  1293. When an application freezes, dropping into MacsBug often reveals that it
  1294. is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  1295. force-quit does nothing.  Is there any hope for someone with debugger
  1296. skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  1297. and make it die a clean death, or should I just restart the Mac?
  1298. -- 
  1299.  Jim Walker
  1300.  
  1301. +++++++++++++++++++++++++++
  1302.  
  1303. >From jonasw@lysator.liu.se (Jonas Wallden)
  1304. Date: 16 Oct 1994 09:57:15 GMT
  1305. Organization: (none)
  1306.  
  1307. walkerj@math.scarolina.edu (James W. Walker) writes:
  1308.  
  1309. >When an application freezes, dropping into MacsBug often reveals that it
  1310. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  1311. >force-quit does nothing.  Is there any hope for someone with debugger
  1312. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  1313. >and make it die a clean death, or should I just restart the Mac?
  1314. >-- 
  1315. > Jim Walker
  1316.  
  1317. The SyncWait loop waits for a parameter block error code to drop below +1
  1318. (which is the value used while the call is in progress), and as we all know
  1319. this error code is 0 (noErr) for a successful request and negative for
  1320. errors.
  1321.  
  1322. So, look at the SyncWait code to see which word it tests (usually something
  1323. like 10(A0)) and set this word to an error code (e.g. FFD5 for fileNotFound)
  1324. and it will often get you out of the lock.
  1325.  
  1326. I've used it successfully in Mosaic several times where it seems to hang
  1327. when I abort a connection, and at other times when the computer won't
  1328. reboot after a crash.
  1329.  
  1330. BTW, I have a MacsBug dcmd which lists error strings from error codes.
  1331. This is great as it's rather difficult to use ObiWan at these times...
  1332. Can't remember if I got it from sumex or a Developer CD, though.
  1333.  
  1334. --
  1335. `.`.   Jonas Wallden                    `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  1336. `.`.`.   Internet: jonasw@lysator.liu.se  `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  1337. `.`.`.`.   AppleLink: sw1369                `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  1338.  
  1339. +++++++++++++++++++++++++++
  1340.  
  1341. >From wysocki@netcom.com (Chris Wysocki)
  1342. Date: Sun, 16 Oct 1994 16:31:58 GMT
  1343. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  1344.  
  1345. In article <walkerj-1510942139180001@192.0.2.1>,
  1346. James W. Walker <walkerj@math.scarolina.edu> wrote:
  1347.  
  1348. >When an application freezes, dropping into MacsBug often reveals that it
  1349. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  1350. >force-quit does nothing.  Is there any hope for someone with debugger
  1351. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  1352. >and make it die a clean death, or should I just restart the Mac?
  1353.  
  1354. Here's a MacsBug dcmd that I wrote a few weeks ago that simply does a
  1355. KillIO for a specified driver.  You might be able to use this when
  1356. you're stuck in _SyncWait to kill the pending request and get out
  1357. safely.  Since it's so small, I've attached it below, along with the
  1358. source code to it; hope you find it useful.
  1359.  
  1360. Chris.
  1361.  
  1362. - ------
  1363.  
  1364. +++++++++++++++++++++++++++
  1365.  
  1366. >From h+@nada.kth.se (Jon W{tte)
  1367. Date: Sun, 16 Oct 1994 20:15:31 +0100
  1368. Organization: Royal Institute of Something or other
  1369.  
  1370. In article <walkerj-1510942139180001@192.0.2.1>,
  1371. walkerj@math.scarolina.edu (James W. Walker) wrote:
  1372.  
  1373. >When an application freezes, dropping into MacsBug often reveals that it
  1374. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  1375. >force-quit does nothing.  Is there any hope for someone with debugger
  1376. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  1377. >and make it die a clean death, or should I just restart the Mac?
  1378.  
  1379. Usually this means a SCSI request isn't being served (or an 
  1380. Ethernet request, or a Serial Port request, or...) This is 
  1381. usually caused because of buggy drivers (like early Applied 
  1382. Engineering drivers, some CD-ROM and MO drivers and version 1.x 
  1383. of the Digidesign card drivers)
  1384.  
  1385. When something hangs in _vSyncWait, it waits for the word at 
  1386. (a0)+10 to go 0 or negative (this is ioResult in the parameter 
  1387. block) One thing you can TRY is:
  1388.  
  1389.     atba
  1390.     sw a0+10 ffff
  1391.     g
  1392.     atc
  1393.     es
  1394.  
  1395. This will make the app halt as soon as it gets to an A-trap (so 
  1396. it won't just get stuck again) Then it fakes an interrupt 
  1397. service routine that sets the result to -1 (an error code) Run 
  1398. with this; and as soon as an A-trap is hit, clear breaks and 
  1399. exit.
  1400.  
  1401. However, since this is a driver that got hosed, chances are 
  1402. you'll run into the same problem an instant later, so it's 
  1403. usually not terribly helpful.
  1404.  
  1405. There are also several conditions which can make this fail:
  1406.  
  1407. - If some idiot masked interrupts, that's the reason you're
  1408.   waiting for an interrupt that's never serviced. Check with TD
  1409.   and look at the Int= figure - should be 0. 7 is real bad.
  1410.  
  1411. - If this was because of a file manager request; the file 
  1412.   manager is now in a meeting for the rest of the day, which 
  1413.   means you earned just about nothing by breaking out.
  1414.  
  1415. - If the driver makes interesting assumptions about the return 
  1416.   value you use (ffff==-1 in this case) OR wants a completion 
  1417.   routine to be called, you're probably hosed anyway.
  1418.  
  1419. There should be a law only competent people can write drivers. 
  1420. Unfortunately it seems to be the other way around with some 
  1421. people "Hey, we've got this interesting hardware we can sell. 
  1422. However, hiring someone expensive to write the drivers would 
  1423. eat into our margin way too much. Isn't Joes 13-year-old kid
  1424. into computers? Have him whip something up and we'll give him a 
  1425. Happy Meal."
  1426.  
  1427. Hardware without drivers is pretty useless.
  1428.  
  1429. Cheers,
  1430.  
  1431.                     / h+
  1432.  
  1433.  
  1434. --
  1435.   Jon W$E4tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  1436.  
  1437.  -- I don't fear death, it's dying that scares me.
  1438.  
  1439.  
  1440. +++++++++++++++++++++++++++
  1441.  
  1442. >From jumplong@aol.com (Jump Long)
  1443. Date: 17 Oct 1994 00:44:01 -0400
  1444. Organization: America Online, Inc. (1-800-827-6364)
  1445.  
  1446. In article <walkerj-1510942139180001@192.0.2.1>,
  1447. walkerj@math.scarolina.edu (James W. Walker) wrote:
  1448.  
  1449. >When an application freezes, dropping into MacsBug often reveals that it
  1450. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  1451. >force-quit does nothing.  Is there any hope for someone with debugger
  1452. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  1453. >and make it die a clean death, or should I just restart the Mac?
  1454.  
  1455. Here are a couple of paragraphs from the article "Asynchronous Routines on
  1456. the Macintosh" in develop issue #13 that explain deadlock conditions and
  1457. SyncWait:
  1458.  
  1459. - ----
  1460.  
  1461. Avoid SyncWait.
  1462.  
  1463. Does your Macintosh just sit there not responding to user events? Drop
  1464. into the debugger and take a look at the code that's executing. Does it
  1465. look like this?
  1466.  
  1467. MOVE.W $0010(A0),D0
  1468. BGT.S  -$04,(PC)
  1469.  
  1470. That's SyncWait, the routine that synchronous calls sit in while waiting
  1471. for a request to complete. Register A0 points to the parameter block used
  1472. to make the call, offset $10 is the ioResult field of the parameter block,
  1473. and SyncWait is waiting for ioResult to be less than or equal to 0
  1474. (noErr).
  1475.  
  1476. The ioResult field is changed by code executing as a result of an
  1477. interrupt. If interrupts are disabled (because the synchronous call was
  1478. made at interrupt time) or if the synchronous call was made to a service
  1479. that's busy, you'll be in SyncWait forever. Take a look at the parameter
  1480. block and where it is in memory, and you'll probably be able to figure out
  1481. which synchronous call was made at interrupt time and which program made
  1482. it.
  1483.  
  1484. - ---
  1485.  
  1486. Deadlock is a state in which each of two or more processes is waiting for
  1487. one of the other processes to release some resource necessary for its
  1488. completion. The resource may be a file, a global variable, or even the
  1489. CPU. The process could, for example, be an application's main event loop
  1490. or a Time Manager task.
  1491.  
  1492. When deadlock occurs on the Macintosh, usually at least one of the
  1493. processes is executing as the result of an interrupt. VBL tasks, Time
  1494. Manager tasks, Deferred Task Manager tasks, completion routines, and
  1495. interrupt handlers can all interrupt an application's main thread of
  1496. execution. When the interrupted process is using a resource that the
  1497. interrupting process needs, the processes are deadlocked.
  1498.  
  1499. For example, suppose a Time Manager task periodically writes data to a
  1500. file by making a synchronous Write request, and an application reads the
  1501. data from its main event loop. Depending on the frequency of the task and
  1502. the activity level of the File Manager, the Time Manager task may often
  1503. write successfully. Inevitably, however, the Time Manager task will
  1504. interrupt the application's Read request and deadlock will occur.
  1505.  
  1506. Because the File Manager processes only one request at a time, any
  1507. subsequent requests must wait for the current request to complete. In this
  1508. case, the synchronous request made by the Time Manager task must wait for
  1509. the application's Read request to complete before its Write request will
  1510. be processed. Unfortunately, the File Manager must wait for the Time
  1511. Manager task to complete before it can resume execution. Each process is
  1512. now waiting for the other to complete, and they will continue to wait
  1513. forever.
  1514.  
  1515. Synchronous requests at interrupt time tend to produce deadlock, because
  1516. the call is queued for processing and then the CPU sits and spins, waiting
  1517. for an interrupt to occur, which signals that the request has been
  1518. completed. If interrupts are turned off, or if a previous pending request
  1519. can't finish because it's waiting to resume execution after the interrupt,
  1520. the CPU will wait patiently (and eternally) for the request to finish -
  1521. until you yank the power cord from the wall.
  1522.  
  1523. - ---
  1524.  
  1525. Read the rest of that article, it'll help you write code that doesn't end
  1526. up in SyncWait.
  1527.  
  1528. - Jim Luther
  1529.  
  1530.  
  1531. +++++++++++++++++++++++++++
  1532.  
  1533. >From walkerj@math.scarolina.edu (James W. Walker)
  1534. Date: Mon, 17 Oct 1994 23:41:46 -0500
  1535. Organization: Dept. of Mathematics, Univ. of South Carolina
  1536.  
  1537. In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
  1538. Long) wrote:
  1539.  
  1540. > Read the rest of that article, it'll help you write code that doesn't end
  1541. > up in SyncWait.
  1542.  
  1543. I guess I didn't make it clear in my original post, but it's not *my* code
  1544. that gets stuck in SyncWait. It's usually Internet apps like Anarchie.  I
  1545. was just wondering whether there was anything I could do when it happens,
  1546. other than restart, and this thread has given me some ideas.  Gee, I can
  1547. hardly wait for the next freeze. :-)
  1548. -- 
  1549.  Jim Walker
  1550.  
  1551. +++++++++++++++++++++++++++
  1552.  
  1553. >From bierman@caelab1.cae.wisc.edu (Peter Bierman)
  1554. Date: Tue, 18 Oct 1994 14:36:31 -0600
  1555. Organization: Happy Frogs, Inc.
  1556.  
  1557. In article <walkerj-1710942341460001@192.0.2.1>,
  1558. walkerj@math.scarolina.edu (James W. Walker) wrote:
  1559.  
  1560. > In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
  1561. > Long) wrote:
  1562. > > Read the rest of that article, it'll help you write code that doesn't end
  1563. > > up in SyncWait.
  1564. > I guess I didn't make it clear in my original post, but it's not *my* code
  1565. > that gets stuck in SyncWait. It's usually Internet apps like Anarchie.  I
  1566. > was just wondering whether there was anything I could do when it happens,
  1567. > other than restart, and this thread has given me some ideas.  Gee, I can
  1568. > hardly wait for the next freeze. :-)
  1569.  
  1570.  
  1571. Well, all of the ideas are good and accurate, but here's an easy fix.
  1572.  
  1573. Do a step (oa-T) till Macsbug says "Will [not] branch". Then type:
  1574.  
  1575. pc=pc+2
  1576.  
  1577. g
  1578.  
  1579. That will jump you out of the loop. It's faster than "fixing" the loop
  1580. condition. Just note that what John said is true: it'll probobly happen
  1581. again withing a short time. Restart right away.
  1582.  
  1583. -Peter
  1584.  
  1585. -- 
  1586.        Peter Bierman       \  The Metropolis  \ The most primitive part of
  1587. the
  1588. bierman@caelab1.cae.wisc.edu\  (614)-846-1911  \   the brain concerns itself
  1589.                              \  600MB Mac Files \     with the "Four F's":
  1590. "I've changed my mind, Hobbes.\  FirstClass GUI  \ Feeding, Fighting,
  1591. Fleeing,
  1592.  people are scum." --Calvin    \  Info-Mac CD-ROM \     and Reproduction.
  1593.  
  1594. +++++++++++++++++++++++++++
  1595.  
  1596. >From richardb@cocytus.demon.co.uk (Richard Buckle)
  1597. Date: Wed, 19 Oct 1994 06:37:42 GMT
  1598. Organization: none
  1599.  
  1600. In article <AAC73A63966886B32@klkmac003.nada.kth.se>,
  1601. h+@nada.kth.se (Jon W{tte) wrote:
  1602.  
  1603. >>When an application freezes, dropping into MacsBug often reveals that it
  1604. >>is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  1605. >>force-quit does nothing.  Is there any hope for someone with debugger
  1606. >>skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  1607. >>and make it die a clean death, or should I just restart the Mac?
  1608.  
  1609. To be honest you can often get away with stepping over the SyncWait test if
  1610. you restart *immediately* you regain control.
  1611.  
  1612. In MacsBug, do a T 40. This should pop you out of any subroutines you're in
  1613. and leave you in the 2-step SyncWait loop; if not, keep doing T 40 until
  1614. you are. If you're at the TST instruction, do one more T to get to the
  1615. branch instruction. Then do PC=PC+2;G to exit the loop. 
  1616.  
  1617. You may need to repeat this process one or more times to regain control.
  1618. Once you have control, go straight to the Finder and to a Restart before
  1619. the driver can bite you again.
  1620.  
  1621. No guarantees and YMMV. However, 90% of the tine this lets be save my work
  1622. :-|
  1623.  
  1624.  
  1625.  
  1626. - -----------------------------------------------------
  1627. Richard Buckle
  1628. richardb@cocytus.demon.co.uk
  1629. Using this darned fine NewsHopper thingy.
  1630.  
  1631.  
  1632. +++++++++++++++++++++++++++
  1633.  
  1634. >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
  1635. Date: Fri, 28 Oct 1994 10:13:36 +0800
  1636. Organization: Department of Computer Science, The University of Western
  1637. Australia
  1638.  
  1639. In article <walkerj-1710942341460001@192.0.2.1>,
  1640. walkerj@math.scarolina.edu (James W. Walker) wrote:
  1641.  
  1642. >I guess I didn't make it clear in my original post, but it's not *my* code
  1643. >that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
  1644.  
  1645. For reliable program (like Anarchie :) disappearing into SyncWait normally
  1646. means that your networking on your machine is stuffed up somehow.
  1647.  
  1648. To get out try this in MacsBug...
  1649.  
  1650.   sm a0+10 ffff
  1651.   g
  1652.  
  1653. What it does is set the ioResult field of the paramblock to -1, indicating
  1654. an error.  You often have to do it a *lot* of times before it comes back
  1655. and often it doesn't work at all.  But it makes you feel like you've got
  1656. control (:
  1657.  
  1658. Share and Enjoy.
  1659. --
  1660. Quinn "The Eskimo!"      "I wasn't the one who fired the heat seeking
  1661.                           population annihilator out the window!"
  1662.   Amaze your friends!  Learn some cool MacsBug or MicroBug commands today (:
  1663.  
  1664. +++++++++++++++++++++++++++
  1665.  
  1666. >From devon_hubbard@taligent.com (Devon Hubbard)
  1667. Date: Fri, 28 Oct 1994 16:20:48 GMT
  1668. Organization: Taligent, Inc.
  1669.  
  1670. In article <quinn-2810941013360001@mac168.cs.uwa.oz.au>,
  1671. quinn@cs.uwa.edu.au (Quinn "The Eskimo!") wrote:
  1672.  
  1673. >In article <walkerj-1710942341460001@192.0.2.1>,
  1674. >walkerj@math.scarolina.edu (James W. Walker) wrote:
  1675. >
  1676. >>I guess I didn't make it clear in my original post, but it's not *my* code
  1677. >>that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
  1678. >
  1679. >For reliable program (like Anarchie :) disappearing into SyncWait normally
  1680. >means that your networking on your machine is stuffed up somehow.
  1681. >
  1682. >To get out try this in MacsBug...
  1683. >
  1684. >  sm a0+10 ffff
  1685. >  g
  1686. >
  1687. >What it does is set the ioResult field of the paramblock to -1, indicating
  1688. >an error.  You often have to do it a *lot* of times before it comes back
  1689. >and often it doesn't work at all.  But it makes you feel like you've got
  1690. >control (:
  1691.  
  1692. Ouch! OUCH! This is assuming that reg A0 really points to the
  1693. cntrlParamBlockRec, which I hate to say doesn't always! I recently ran
  1694. into a vSyncWait problem (on an 8100av) that lead to fingering the
  1695. offending driver by looking at the data moved off D2 and matching that as
  1696. a DCE entry with the help of Macsbug's 'drvr' dcmd.  In every case of
  1697. vSyncWait hang, a0 WAS NOT pointing to a valid paramblock so do a
  1698.  
  1699.    dm a0 cntrlparamblockrec
  1700.  
  1701. before the 'sm' and make sure it looks like a valid paramblock, or you'll
  1702. surely be rebooting thereafter.
  1703.  
  1704. dEVoN
  1705.  
  1706. - -----------------------------------------------------------------------
  1707. Devon Hubbard                                               Silicon Pilot
  1708. devon_hubbard@taligent.com                                  Taligent, Inc
  1709.  
  1710. ---------------------------
  1711.  
  1712. >From macrshap@bbn.com (Richard Shapiro)
  1713. Subject: having trouble with AEInteractWithUser & drag manager
  1714. Date: 9 Oct 1994 17:09:27 GMT
  1715. Organization: Bolt, Beranek and Newman Inc.
  1716.  
  1717. I'm in the process of adding some drag-support to an application. It's
  1718. working ok when the application is selected, so the underlying drag
  1719. management seems fine. But usually, I want to drag when another
  1720. application is selected (ie I'll be dragging from that other application).
  1721. In this case, when my app receives the drag, it needs to interact with the
  1722. user before proceeding. This is where I'm stuck. 
  1723.  
  1724. I've set the InteractionAllowed flag to kAEInteractWithLocal (the default,
  1725. I know, but I thought I'd be explicit), and I carefully call
  1726. AEInteractWithUser before attempting any interaction. I'm calling it
  1727. without a timeout (kNoTimeOut), without a notification rec (should be OK
  1728. since I have the relevant BNDL, FREF and ICN# resources defined), and with
  1729. a very simple idle procedure which essentially does nothing (since at the
  1730. moment nothing in my app cares about update or activate events). 
  1731.  
  1732. What I expected to happen was the usual flashing in the
  1733. current-application icon (on the right edge of the menubar), which would
  1734. allow me to bring my app to the front. What actually happens is...nothing:
  1735. no flashing, no process paying attention to mouse clicks, hence no way to
  1736. select my application (which has received the drop and is waiting in the
  1737. call to AEInteractWithUser) so that I can interact with it. All I can do
  1738. is cmd-opt-escape to force a quit.
  1739.  
  1740. What am I doing wrong? I'm assuming it must be one of two things: either
  1741. it's illegal to have user interaction after receiving a drop but before
  1742. acknowledging receipt; or I need to handle something in my idle function
  1743. which I'm not currently handling.
  1744.  
  1745. Any suggestions? If it matters, I'm using CW 4.5 C, and running System 7.1
  1746. on a q660av with drag extensions and the drag-ware Finder (7.1.3). The
  1747. drag flavors I'm handling at the moment are 'hfs ' and 'TEXT'.
  1748.  
  1749. Please copy followups to email -- thanks.
  1750.  
  1751. -- 
  1752. rs/macrshap@bbn.com
  1753.  
  1754. +++++++++++++++++++++++++++
  1755.  
  1756. >From Jens Alfke <jens_alfke@powertalk.apple.com>
  1757. Date: Mon, 10 Oct 1994 22:12:55 GMT
  1758. Organization: Apple Computer
  1759.  
  1760. Richard Shapiro, macrshap@bbn.com writes:
  1761. > What am I doing wrong? I'm assuming it must be one of two things: either
  1762. > it's illegal to have user interaction after receiving a drop but before
  1763. > acknowledging receipt
  1764.  
  1765. Bingo -- more specifically, it's illegal to cause a process switch while
  1766. inside a drag handler, since the drag handlers are called via a lightweight
  1767. process switch that is not compatible with the regular kind of process
  1768. switch. While you're in a drag handler, WNE is hacked to do nothing for
  1769. compatibility, but other ways to interact (such as calling AEInteractWithUser
  1770. or SetFrontProcess) will choke your machine.
  1771.  
  1772. Moral: Wait until after the drag finishes to try to interact with the user.
  1773.  
  1774. --Jens Alfke                           jens_alfke@powertalk.apple.com
  1775.                    "A man, a plan, a yam, a can of Spam ... Bananama!"
  1776.  
  1777. +++++++++++++++++++++++++++
  1778.  
  1779. >From macrshap@bbn.com (Richard Shapiro)
  1780. Date: 11 Oct 1994 01:54:10 GMT
  1781. Organization: Bolt, Beranek and Newman Inc.
  1782.  
  1783. In article <1994Oct10.221255.26429@gallant.apple.com>, Jens Alfke
  1784. <jens_alfke@powertalk.apple.com> wrote:
  1785.  
  1786. > Bingo -- more specifically, it's illegal to cause a process switch while
  1787. > inside a drag handler, since the drag handlers are called via a lightweight
  1788. > process switch that is not compatible with the regular kind of process
  1789. > switch. While you're in a drag handler, WNE is hacked to do nothing for
  1790. > compatibility, but other ways to interact (such as calling
  1791. AEInteractWithUser
  1792. > or SetFrontProcess) will choke your machine.
  1793. > Moral: Wait until after the drag finishes to try to interact with the user.
  1794.  
  1795. OK, I eventually came to that conclusion myself. I guess it's good to have
  1796. it validated... 
  1797.  
  1798. Problem is, I really need user interaction to complete the processing of
  1799. the drop. So, I tried to get around it by stashing the DragReference in a
  1800. global, setting a flag, returning from the handler, and then dealing with
  1801. the stashed DragReference when I'm back in the main event loop (depending
  1802. on the flag, of course). This doesn't work either. I can interact with the
  1803. user, but it looks as though the information associated with the
  1804. DragReference vanishes once the handler is exited. At least, I can't get
  1805. CountDragItems and the like to work properly outside the handler context.
  1806. Are these supposed to work outside the handler?
  1807.  
  1808. That seems to leave me with one final option: I have to get *all* the data
  1809. out of the DragReference while I'm in the handler, stash the whole pile
  1810. somewhere, exit the handler, and process the data later. Yucch, that's
  1811. pretty awful. Is there another possibility I'm missing here?
  1812.  
  1813. For now, I "fixed" the application to run without user-interaction when it
  1814. isn't in the foreground (which can only happen as a result of a drop).
  1815. It's better than nothing, but really not what I want...
  1816.  
  1817. -- 
  1818. rs/macrshap@bbn.com
  1819.  
  1820. +++++++++++++++++++++++++++
  1821.  
  1822. >From Jens Alfke <jens_alfke@powertalk.apple.com>
  1823. Date: Tue, 11 Oct 1994 17:28:36 GMT
  1824. Organization: Apple Computer
  1825.  
  1826. Richard Shapiro, macrshap@bbn.com writes:
  1827. > That seems to leave me with one final option: I have to get *all* the data
  1828. > out of the DragReference while I'm in the handler, stash the whole pile
  1829. > somewhere, exit the handler, and process the data later. Yucch, that's
  1830. > pretty awful. Is there another possibility I'm missing here?
  1831.  
  1832. Since you can't possibly use the DragReference after the sender disposes of
  1833. it, I think this is your only option. Is it that bad? Get the data you want
  1834. to use, stash it somewhere temporary, and when you get back into your event
  1835. loop ask the user what to do with it.
  1836.  
  1837. --Jens Alfke                           jens_alfke@powertalk.apple.com
  1838.                    "A man, a plan, a yam, a can of Spam ... Bananama!"
  1839.  
  1840. +++++++++++++++++++++++++++
  1841.  
  1842. >From macrshap@bbn.com (Richard Shapiro)
  1843. Date: 11 Oct 1994 22:25:03 GMT
  1844. Organization: Bolt, Beranek and Newman Inc.
  1845.  
  1846. In article <1994Oct11.172836.17257@gallant.apple.com>, Jens Alfke
  1847. <jens_alfke@powertalk.apple.com> wrote:
  1848.  
  1849.  
  1850. > Since you can't possibly use the DragReference after the sender disposes of
  1851. > it
  1852.  
  1853. As expected.
  1854.  
  1855. > I think this is your only option. Is it that bad? Get the data you want
  1856. > to use, stash it somewhere temporary, and when you get back into your event
  1857. > loop ask the user what to do with it.
  1858.  
  1859. No, it's not as bad as I thought. In fact it's already done and the result
  1860. is cleaner than my original plan :)
  1861.  
  1862. Now on to my next drag-manager question: receiving promise-hfs drags in an
  1863. application other than the Finder. Details in another posting...
  1864.  
  1865. -- 
  1866. rs/macrshap@bbn.com
  1867.  
  1868. +++++++++++++++++++++++++++
  1869.  
  1870. >From leonardr@netcom.com (Leonard Rosenthol)
  1871. Date: Wed, 19 Oct 1994 22:01:35 GMT
  1872. Organization: Aladdin Systems, Inc.
  1873.  
  1874. In article <macrshap-1110941825500001@ipa.bbn.com>, macrshap@bbn.com
  1875. (Richard Shapiro) wrote:
  1876.  
  1877. > > I think this is your only option. Is it that bad? Get the data you want
  1878. > > to use, stash it somewhere temporary, and when you get back into your
  1879. event
  1880. > > loop ask the user what to do with it.
  1881. > No, it's not as bad as I thought. In fact it's already done and the result
  1882. > is cleaner than my original plan :)
  1883.    What I've been doing in this case is to get all the info from the Drag,
  1884. and then send it back to myself in an Apple event (but NOT in sendToSelf
  1885. mode).  This works quite nicely...
  1886.  
  1887.  
  1888. Leonard
  1889. - ------------------------------------------------------------------------
  1890. Leonard Rosenthol                      Internet:       leonardr@netcom.com
  1891. Director of Advanced Technology        AppleLink:      MACgician
  1892. Aladdin Systems, Inc.                  GEnie:          MACgician
  1893.  
  1894. +++++++++++++++++++++++++++
  1895.  
  1896. >From jonpugh@netcom.com (Jon Pugh)
  1897. Date: Wed, 26 Oct 1994 07:08:53 GMT
  1898. Organization: Will hack for food
  1899.  
  1900. Leonard Rosenthol (leonardr@netcom.com) wrote:
  1901. >    What I've been doing in this case is to get all the info from the Drag,
  1902. > and then send it back to myself in an Apple event (but NOT in sendToSelf
  1903. > mode).  This works quite nicely...
  1904.  
  1905. I actually send the event twice.  Once to myself as record only, and then
  1906. again with signature addressing so that it goes through the event loop.
  1907. That way you can record the event too.
  1908.  
  1909. Jon
  1910.  
  1911.  
  1912. ---------------------------
  1913.  
  1914. End of C.S.M.P. Digest
  1915. **********************
  1916.  
  1917.  
  1918. ---------------------------------------------------------------------
  1919.  
  1920. NOTE:  The following Macintosh file(s) are enclosed with this
  1921. message, in BinHex format.  If your mail system does not convert
  1922. BinHex files automatically, you will need to transfer the message to
  1923. a Mac and run the BinHex application to decode it.
  1924.  
  1925. Filename: KillIO dcmd.sit    Size:  3181 bytes
  1926.  
  1927. ---------------------------------------------------------------------
  1928.  
  1929. (This file must be converted with BinHex 4.0)
  1930.  
  1931.  
  1932.